
#include "include/bobo.h"

#define i2 (i*i)

//JNIEXPORT jstring get(JNIEnv *env, jobject clazz, jobject ctx, jint t)
//{
//    char *ar = NULL;
//    if (isLegalAccess(env, clazz, ctx))
//    {
//        switch (t)
//        {
//            case 1:
//                ar = "2771448623\0";
//                break;
//            case 2:
//                ar = "4ca9a0884a71e27a1fec342e2aa3c90b\0";
//                break;
//            case 3:
//                ar = "wxb0aacc5c6e6d639c\0";
//                break;
//            case 4:
//                ar = "fee6ee21ad0d11f8e43def33e77a3717\0";
//                break;
//            case 5:
//                //qqid 1106093699  1106076711
//                ar = "1106309787\0";
//                break;
//            case 6:
//                //qqkey i7vaRLCs7oIYHuA0  HcgJcmPVDWMklmh9
//                ar = "wcZJONixMVysQaFF\0";
//                break;
//            case 7:
//                ar = "http://api.shangxueba.com/\0";
//                break;
//            case 8:
//                ar = "vKxzjx4a1dNOMVbpMWMHIVRR\0";
//                break;
//            case 9:
//                ar = "80a21c1ad0dd3a0c4e9b7f5fc5eaf2b9\0";
//                break;
//            case 10:
//                ar = "HHR40Y0X0P0IRH467U6CM0D1782GTRQUWF6S";
//                break;
//            case 11:
//                ar = "appkey";
//                break;
//            case 12:
//                ar = "1489154932";
//                break;
//        }
//    } else
//    {
//        ar = UNSIGNATURE;
//    }
//    return (*env)->NewStringUTF(env, ar);
//}

JNIEXPORT jstring md5(JNIEnv *env, jobject clazz, jobject ctx, jstring str)
{
    if (isLegalAccess(env, clazz, ctx))
    {
        return raw_md5(env, clazz, str);
    } else
    {
        return (*env)->NewStringUTF(env, UNSIGNATURE);
    }
}

JNIEXPORT jstring _md5(JNIEnv *env, jobject clazz, jstring str)
{
    return raw_md5(env, clazz, str);
}

JNIEXPORT jstring sha1(JNIEnv *env,jobject clazz,jstring str)
{
    return raw_sha1(env, clazz, str);
}

JNIEXPORT jstring getSingleSign(JNIEnv *env, jobject clazz, jobject ctx)
{
    return raw_getSign(env, clazz, ctx);
}

JNIEXPORT jstring getSign(JNIEnv *env, jobject thiz, jobject context)
{
    return GetSignature(env, thiz, context);
}

jboolean isLegalAccess(JNIEnv *env, jobject clazz, jobject context)
{
    return (jboolean)(checkSignature(env, clazz, context) > 0);
}

jint checkSignature(JNIEnv *env, jobject thiz, jobject context)
{
    jstring md5str = getSign(env,thiz, context);
    const char *md5char = (*env)->GetStringUTFChars(env,md5str, 0);
    if(strcmp(md5char, app_signature) != 0)
    {
        return -1;
    }
    return 1;
}

JNIEXPORT jstring aesEcbEncrypt(JNIEnv *env, jobject clazz, jobject ctx, jstring str_)
{
    if (isLegalAccess(env, clazz, ctx))
    {
        uint8_t AES_KEY[] = "HHR40Y0X0P0IRH467U6CM0D1782GTRQUWF6S";
        return raw_aesEcbEncrypt(env, clazz, AES_KEY, str_);
    } else
    {
        return (*env)->NewStringUTF(env, UNSIGNATURE);
    }
}

JNIEXPORT jstring _aesEcbEncrypt(JNIEnv *env, jobject clazz, jstring key, jstring str_)
{
    return raw_aesEcbEncrypt2(env, clazz, key, str_);
}

JNIEXPORT jstring _aesCbcEncrypt(JNIEnv *env, jobject clazz, jstring iv, jstring key, jstring str_)
{
    return raw_aesCbcEncrypt(env, clazz, iv, key, str_);
}

JNIEXPORT jstring _aesCbcDecrypt(JNIEnv *env, jobject clazz, jstring iv, jstring key, jstring str_)
{
    return raw_aesCbcDecrypt(env, clazz, iv, key, str_);
}

JNIEXPORT jstring aesEcbDecrypt(JNIEnv *env, jobject clazz, jobject ctx, jstring str_)
{
    if (isLegalAccess(env, clazz, ctx))
    {
        uint8_t AES_KEY[] = "HHR40Y0X0P0IRH467U6CM0D1782GTRQUWF6S";
        return raw_aesEcbDecrypt(env, clazz, AES_KEY, str_);
    } else
    {
        return (*env)->NewStringUTF(env, UNSIGNATURE);
    }
    //不用系统自带的方法NewStringUTF是因为如果desResult是乱码,会抛出异常
    //return charToJstring(env,desResult);
}

JNIEXPORT jstring _aesEcbDecrypt(JNIEnv *env, jobject clazz, jstring key, jstring str_)
{
    return raw_aesEcbDecrypt2(env, clazz, key, str_);
    //不用系统自带的方法NewStringUTF是因为如果desResult是乱码,会抛出异常
    //return charToJstring(env,desResult);
}

JNIEXPORT jint WriteString2File(JNIEnv *env, jobject clazz, jstring path, jstring content)
{
    return WriteStringToFile(env, clazz, path, content);
}


JNIEXPORT jstring ReadString(JNIEnv *env, jobject clazz, jstring path)
{
    return ReadStringFromFile(env, clazz, path);
}

JNIEXPORT jstring getDeviceUniqueCode(JNIEnv *env, jobject thiz, jobject context)
{
    return getDeviceUnique(env, thiz, context);
}


JNIEXPORT jint DeleteDir(JNIEnv *env, jobject jclazz, jstring path)
{
    return __delete_dir(env, jclazz, path);
}

jstring EncodeBase64(JNIEnv *env, jobject jclazz, jstring str)
{
    return __encode_base64(env, jclazz, str);
}

jstring DecodeBase64(JNIEnv *env, jobject jclazz, jstring str)
{
    return __decode_base64(env, jclazz, str);
}

// Java和JNI函数的绑定表
static JNINativeMethod method_table[] = {
        {"md5",              "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;", (void *) md5},
        {"md5",              "(Ljava/lang/String;)Ljava/lang/String;",                      (void *) _md5},
        {"sha1",             "(Ljava/lang/String;)Ljava/lang/String;",                      (void *) sha1},
        {"getSingleSign",   "(Ljava/lang/Object;)Ljava/lang/String;",                   (void *) getSingleSign},
        {"getSign",          "(Ljava/lang/Object;)Ljava/lang/String;",                   (void *) getSign},
        {"aesEcbEncrypt",       "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;", (void *) aesEcbEncrypt},
        {"aesEcbEncryptWithKey", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void *) _aesEcbEncrypt},
        {"aesEcbDecrypt",       "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;", (void *) aesEcbDecrypt},
        {"aesEcbDecryptWithKey", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void *) _aesEcbDecrypt},
        {"aesCbcEncrypt",   "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void *) _aesCbcEncrypt},
        {"aesCbcDecrypt",   "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void *) _aesCbcDecrypt},
        {"writeString",     "(Ljava/lang/String;Ljava/lang/String;)I",                  (void *) WriteString2File},
        {"readString",      "(Ljava/lang/String;)Ljava/lang/String;",                  (void *) ReadString},
        {"deleteDir",       "(Ljava/lang/String;)I",                                      (void *) DeleteDir},
        {"encodeBase64",    "(Ljava/lang/String;)Ljava/lang/String;",                  (void *) EncodeBase64},
        {"decodeBase64",    "(Ljava/lang/String;)Ljava/lang/String;",                   (void *) DecodeBase64},
        {"getDeviceCode",   "(Ljava/lang/Object;)Ljava/lang/String;",                  (void *) getDeviceUniqueCode}};

// 注册native方法到java中
static int registerNativeMethods(JNIEnv *env, const char *className,
                                 JNINativeMethod *gMethods, int numMethods)
{
    jclass clazz;
    clazz = (*env)->FindClass(env, className);
    if (clazz == NULL)
    {
        return JNI_FALSE;
    }
    if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0)
    {
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

int register_ndk_load(JNIEnv *env)
{
    // 注册调用方法
    return registerNativeMethods(env, JNIREG_CLASS, method_table, NELEM(method_table));
}

JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
    JNIEnv *env = NULL;
    jint result = -1;

    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK)
    {
        return result;
    }

    register_ndk_load(env);

    // 返回jni的版本
    return JNI_VERSION_1_4;
}